package com.example.front.serivce;

import java.net.URISyntaxException;

import com.example.common.constant.AndonCode;
import com.example.common.constant.SendWeChatMessage;
import com.example.common.dto.ListDto;
import com.example.common.dto.Pagination;
import com.example.common.exception.BusinessException;
import com.example.front.component.WebSocketServer;
import com.example.front.dto.*;
import com.example.front.entity.*;
import com.example.front.entity.Box;

import com.example.front.mapper.IncidentMapper;
import com.example.front.mapper.MessageLoggingMapper;
import com.example.front.until.TimesUntil;
import com.example.interceptor.UserContext;
import com.example.passport.entity.User;
import com.example.passport.mapper.UserMapper;
import com.example.passport.service.UserService;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import org.fusesource.mqtt.client.BlockingConnection;
import org.fusesource.mqtt.client.MQTT;
import org.fusesource.mqtt.client.QoS;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class IncidentService {

    @Resource
    IncidentMapper incidentMapper;
    @Resource
    GatewayService gatewayService;
    @Resource
    CategoryService categoryService;
    @Resource
    BoxService boxService;
    @Resource
    ButtonService buttonService;
    @Resource
    LineService lineService;
    @Resource
    EventService eventService;
    @Resource
    UserService userService;
    @Resource
    UserMapper userMapper;
    @Resource
    WorkshopService workshopService;
    @Resource
    CraftService craftService;
    @Resource
    LevelService levelService;
    @Resource
    WebSocketServer webSocketServer;
    @Resource
    MaintenanceService maintenanceService;
    @Resource
    MaintenanceUserService maintenanceUserService;
    @Resource
    EquipmentService equipmentService;
    @Resource
    MessageLoggingService messageLoggingService;

    /**
     * 列出事件记录
     */
    public ListDto<IncidentDto> listIncident(IncidentSearchDto condition, Pagination pagination) {
        long total = incidentMapper.count(condition);
        if (total <= 0) {
            return new ListDto<>(new ArrayList<>(), pagination);
        }
        pagination.setTotal(total);
        List<Incident> incidentList = incidentMapper.findAll(condition, pagination);
        List<IncidentDto> incidentDtoList = incidentList.stream().map(incident -> {
            IncidentDto incidentDto = new IncidentDto();
            BeanUtils.copyProperties(incident, incidentDto);
            incidentDto.setName(boxService.findById(incidentDto.getTenantId(), incidentDto.getBoxId()).getName());
            incidentDto.setEventName(eventService.findById(incidentDto.getTenantId(), incidentDto.getEventId()));
            incidentDto.setLineName(lineService.findById(incidentDto.getLineId(), incidentDto.getTenantId()).getName());
            incidentDto.setWorkshopName(workshopService.findById(incidentDto.getWorkshopId(), incidentDto.getTenantId()).getName());
            if (!"".equals(incidentDto.getUserId())) {
                String username = "";
                String userIds = incidentDto.getUserId();
                if (userIds != null && !"".equals(userIds)){
                    for (String s : userIds.split(",")) {
                        if (userService.findUserById(Long.parseLong(s)) != null) {
                            username += userService.findUserById(Long.parseLong(s)).getName() + " ";
                        }
                    }
                }
                incidentDto.setUserName(username);
            }
            if (incident.getResponseAt() != null) {
                long time = incident.getResponseAt().getTime() - incident.getCreatedAt().getTime();
                incidentDto.setResponseTime((time / 60000) + 1);
            }
//            if (incident.getCompleteAt() != null) {
//
//                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//                String format = simpleDateFormat.format(incident.getCompleteAt());
//
//                System.out.println("==========================>");
//                System.out.println(incident.getCompleteAt());
//                long time0 = incident.getCompleteAt().getTime() - incident.getResponseAt().getTime();
//                incidentDto.setCompleteTime((time0 / 60000) + 1);
//            }
            return incidentDto;
        }).collect(Collectors.toList());
        return new ListDto<>(incidentDtoList, pagination);
    }


    public ListDto<EventTimesDto> evenTimes(IncidentSearchDto condition, Pagination pagination) {
        long total = incidentMapper.count(condition);
        if (total <= 0) {
            return new ListDto<>(new ArrayList<>(), pagination);
        }
        pagination.setTotal(total);
        EventSearchDto eventSearchDto = new EventSearchDto();
        eventSearchDto.setTenantId(condition.getTenantId());
        ListDto<EventDto> eventDtoListDto = eventService.listEvent(eventSearchDto, pagination);
        System.out.println("eventss" + eventDtoListDto);
        List<EventTimesDto> eventTimesDtoList = eventDtoListDto.getList().stream().map(event -> {
            EventTimesDto eventTimesDto = new EventTimesDto();
            BeanUtils.copyProperties(event, eventTimesDto);
            condition.setEventId(event.getId());
            eventTimesDto.setTimes(incidentMapper.count(condition));
            return eventTimesDto;
        }).collect(Collectors.toList());
        return new ListDto<>(eventTimesDtoList, pagination);
    }

    public Incident getincident(IncidentCreateDto incidentCreateDto) {
        Gateway gateway = gatewayService.findByCode(incidentCreateDto.getCode());
        incidentCreateDto.setTenantId(gateway.getTenantId());
//        Category category = categoryService.findByName(incidentCreateDto.getTenantId(), incidentCreateDto.getModel());
        Box box = boxService.findByGatewayAddr(incidentCreateDto.getTenantId(), gateway.getId(), incidentCreateDto.getDevAddr());
        Button button = Button.builder().tenantId(incidentCreateDto.getTenantId()).key(incidentCreateDto.getKeyNum()).categoryId(box.getCategoryId()).build();
        ButtonDto buttonDto = buttonService.event(button);
        Line line = lineService.findById(box.getLineId(), incidentCreateDto.getTenantId());
        Long levelId = 0l;
//        if (boxService.boxEventUserList(box.getId()) != null) {
//            for (BoxEventUserDto boxEventUserDto : boxService.boxEventUserList(box.getId())) {
//                if (buttonDto.getEventId() == boxEventUserDto.getEventId()) {
//                    levelId = boxEventUserDto.getLevelId();
//                }
//            }
//        }
        Incident incident = Incident.builder().
                boxId(box.getId()).
                buttonId(buttonDto.getId()).
                eventId(buttonDto.getEventId()).
                tenantId(incidentCreateDto.getTenantId()).
                workshopId(line.getWorkshopId()).
                lineId(box.getLineId()).
                levelId(levelId).
                build();
        if (AndonCode.ANDON_CANCEL.getCode().equals(incidentCreateDto.getKeyNum())) {
            incident.setProcessingStatus(AndonCode.ANDON_CANCEL.getCode());
            incidentMapper.updateCompleteAt(incident);
        }
        return incident;
    }

//    /**
//     * 创建事件记录
//     */
//    @Transactional
//    public NoticeDto create(@Valid IncidentCreateDto incidentCreateDto) throws Exception {
//
//        Incident incident = getincident(incidentCreateDto);
//        Incident incident1 = incidentMapper.checkCreate(incident);
//        //根据按键设置完成状态
//        incident.setProcessingStatus(AndonCode.ANDON_NO_REPORTED.getCode());
//        incidentMapper.updateProcessingStatus(incident1);
//
//        if (incident1 == null) {
//            incidentMapper.create(incident);
//        } else if (incident1.getCompleteAt() != null) {
//            incidentMapper.create(incident);
//        } else {
//            throw new BusinessException("请勿频繁请求");
//        }
////        Long UserId = LineUserService.findUserId(incident.getTenantId(), incident.getLineId(), incident.getEventId()).getUserId();
////        String userApi = userService.findById(UserId).getApiToken();
//        Line line1 = lineService.findById(incident.getLineId(), incident.getTenantId());
//        Box box1 = boxService.findById(incident.getTenantId(), incident.getBoxId());
//        String eventName = eventService.findById(incident.getTenantId(), incident.getEventId());
//        String workName = workshopService.findById(incident.getWorkshopId(), incident.getTenantId()).getName();
//        String craftName = craftService.findById(box1.getCraftId(), incident.getTenantId()).getName();
//        NoticeDto noticeDto = new NoticeDto();
//        noticeDto.setLineName(line1.getName());
//        noticeDto.setCraftName(craftName);
////        noticeDto.setUserApi(userApi);
//        noticeDto.setBoxName(box1.getName());
//        noticeDto.setEventName(eventName);
//        noticeDto.setWorkshopName(workName);
//        List<BoxEventUserDto> boxEventUserDto = boxService.boxEventUserList(box1.getId());
//        if (boxEventUserDto != null) {
//            for (BoxEventUserDto eventUserDto : boxEventUserDto) {
//                if (eventUserDto.getEventId() == incident.getEventId()) {
//                    Map<Long, String> map = eventUserDto.getUser();
//                    List<User> list = new ArrayList<>();
//                    for (Long id : map.keySet()) {
//                        User user = userService.findById(id);
//                        list.add(user);
//                    }
//                    noticeDto.setUser(list);
//                }
//            }
//        }
//        String userid="";
//        if(noticeDto.getUser()!=null){
//            for (int i = 0; i <noticeDto.getUser().size() ; i++) {
//                if (i==noticeDto.getUser().size()-1){
//                    userid+=noticeDto.getUser().get(i).getId();
//                }else {
//                    userid+=noticeDto.getUser().get(i).getId()+",";
//                }
//            }
//        }
//        Incident ask=new Incident();
//        ask.setUserId(userid);
//        ask.setId(incident.getId());
//        ask.setTenantId(incident.getTenantId());
//        incidentMapper.updateUserId(ask);
//        return noticeDto;
//    }

    /**
     * 创建事件记录
     */
    @Transactional
    public NoticeDto create(@Valid IncidentCreateDto incidentCreateDto) throws Exception {
        System.out.println(incidentCreateDto);
//code=13200131558959695940, model=SP-AD433A, devAddr=1, keyNum=1, keySta=1
//        User user = UserContext.getUser();
//        incidentCreateDto.setTenantId(1L);
        //获取网关
        String code = incidentCreateDto.getCode();
        if (code != null && !"".equals(code)) {
            //网关
            Gateway gateway = gatewayService.findByCode(code);
            incidentCreateDto.setTenantId(gateway.getTenantId());
            //网关 + 地址获取按钮盒
            Box box = boxService.findByGatewayAddr(incidentCreateDto.getTenantId(),
                    gateway.getId(), incidentCreateDto.getDevAddr());

            //获取按钮盒下面绑定的按键 定位 当前事件id keyNum
            Map<String, String> categoryMap = categoryService.categoryEvent(box.getCategoryId(), incidentCreateDto.getKeyNum());
            String eventName = categoryMap.get("name");
            Long eventId = Long.parseLong(String.valueOf(categoryMap.get("id")));
            Long bid = Long.parseLong(String.valueOf(categoryMap.get("bid")));

            //判断是否是取消按钮 当摁下取消时 取消同盒子没有完成的请求 并推送微信消息
            if ("取消".equals(eventName)) {
                //找到需要取消的按钮
                List<Incident> cancelIncident = incidentMapper.selectCancel(box.getId());
                System.out.println(cancelIncident);
                if (cancelIncident.size() > 0 && !"".equals(cancelIncident.get(0).getUserId())) {
                    Incident incident = cancelIncident.get(0);
                    List<String> userList = Arrays.asList(incident.getUserId().split(","));
                    List<User> byIds = userMapper.findByIds(userList);

                    for (User byId : byIds) {
                        String toUser = byId.getToUser();
                        if ("".equals(toUser)) {
                            continue;
                        }
                        SendWeChatMessage weChat = new SendWeChatMessage();
                        String content = "<div>" + TimesUntil.getDate("yyyy年MM月dd日 HH时mm分ss秒") + "</div> " +
                                "<div>" + incident.getText() + "</div>" +
                                "<div>取消</div>";
                        weChat.sendWeChatMessage(
                                toUser, "取消呼叫", content, "");
                    }
                }

                incidentMapper.cancel(box.getId(), TimesUntil.getDate(), AndonCode.ANDON_CANCEL.getCode());
                return null;
            }

            //响应数据
            NoticeDto noticeDto = new NoticeDto();
            noticeDto.setBoxId(box.getId());

            //插入数据
            Incident incident = new Incident();
            incident.setTenantId(gateway.getTenantId());
            incident.setBoxId(box.getId());
            incident.setEventId(eventId);
            incident.setButtonId(bid);
            incident.setProcessingStatus(AndonCode.ANDON_NO_REPORTED.getCode());

            //查询产线是否存在
            Line line = lineService.findById(box.getLineId());
            if (line != null && line.getId() != null && line.getId() != 0) {
                //获取维修班组
                Maintenance maintenance = new Maintenance();
                //tab
                maintenance.setLineId(String.valueOf(line.getId()));
                Maintenance maintenanceData = maintenanceService.selectOne(maintenance);

                //获取车间
                Workshop workshop = workshopService.findById(line.getWorkshopId());
                noticeDto.setWorkshopName(workshop.getName());

                incident.setLineId(line.getId());
                incident.setWorkshopId(workshop.getId());


                if (maintenanceData != null) { //存在维修班组 获取按键对应的人员信息
                    MaintenanceUser maintenanceUser = new MaintenanceUser();
                    maintenanceUser.setTenantId(gateway.getTenantId());
                    maintenanceUser.setMId(maintenanceData.getId());
                    maintenanceUser.setEventId(eventId);
                    List<MaintenanceUser> maintenanceUserList = maintenanceUserService.selectList(maintenanceUser);
                    List<User> userList = new ArrayList<>();
                    String userStr = "";
                    if (maintenanceUserList != null) {
                        incident.setLevelId(maintenanceUserList.get(0).getLevelId());
                        noticeDto.setLevelId(maintenanceUserList.get(0).getLevelId());

                        for (MaintenanceUser list : maintenanceUserList) {
                            User userById = userService.findById(list.getUserId());
                            if (userById != null && userById.getId() != 0) {
                                userList.add(userById);
                                if ("".equals(userStr)) {
                                    userStr += userById.getName();
                                } else {
                                    userStr += ("," + userById.getName());
                                }
                            }
                        }
                    }
                    //工艺不为空获取工艺信息
                    if (box.getCraftId() != null) {
                        Craft craft = craftService.findById(box.getCraftId(), gateway.getTenantId());
                        if (craft != null) {
                            noticeDto.setCraftName(craft.getName());
                        }
                    }
                    //设备不为空获取设备信息
                    if (box.getEquId() != null) {
                        Equipment equipment = equipmentService.findById(box.getEquId());
                        if (equipment != null) {
                            noticeDto.setEquName(equipment.getName());
                            noticeDto.setEquNum(equipment.getCurrentCoding());
                            noticeDto.setMaintainGroup(equipment.getMaintainGroup());
                        }
                    }

                    noticeDto.setMaintenanceName(maintenanceData.getName());
                    noticeDto.setLineName(line.getName());
                    noticeDto.setEventName(eventName);
                    noticeDto.setUser(userList);

                    System.out.println("维修班组" + userStr);

                    String strUserId = "0";
                    for (User user : userList) {
                        if ("0".equals(strUserId)) {
                            strUserId = user.getId() + ",";
                        } else {
                            strUserId += (user.getId() + ",");
                        }
                    }
                    incident.setUserId(strUserId);

                    create(incident);
                    noticeDto.setId(incident.getId());
                    return noticeDto;

                } else { //没有维修班组 直接插入数据
                    create(incident);
                }


            } else {  //没有产线信息 直接插入数据
                create(incident);
            }

        }

        return null;
    }

    public void create(Incident incident) {
//        System.out.println("-------------------------------->");
//        System.out.println(incident);
        incidentMapper.create(incident);
    }


    @Transactional
    public void startResponse(@Valid IncidentCreateDto incidentCreateDto) {
        Incident incident = getincident(incidentCreateDto);
        Incident incident1 = incidentMapper.checkCreate(incident);
        incidentMapper.updateProcessingStatus(incident1);
        if (incident1 == null) {
            throw new BusinessException("请求异常");
        } else {
            if (incident1.getCompleteAt() != null) {
                throw new BusinessException("请求异常");
            }
            if (incident1.getResponseAt() != null) {
                throw new BusinessException("请勿频繁请求");
            }

            tuisong(incident1, "处理中");

            incident1.setResponseAt(new Date());
            incident1.setProcessingStatus(AndonCode.ANDON_MAINTENSNCE.getCode());
            incidentMapper.startResponse(incident1);
        }

    }

    @Transactional
    public void finish(@Valid IncidentCreateDto incidentCreateDto) {
        Incident incident = getincident(incidentCreateDto);
        Incident incident1 = incidentMapper.checkCreate(incident);

        incidentMapper.updateProcessingStatus(incident1);
        if (incident1 == null) {
            throw new BusinessException("请求异常");
        } else {
            if (incident1.getResponseAt() == null) {
                throw new BusinessException("请求异常");
            }
            if (incident1.getCompleteAt() != null) {
                throw new BusinessException("请求异常");
            }
            tuisong(incident1, "已完成");
            incident1.setCompleteAt(new Date());
            incident1.setProcessingStatus(AndonCode.ANDON_FINISH.getCode());
            incidentMapper.finish(incident1);
        }
    }

    public void tuisong(Incident incident, String foot) {
        List<String> strings = Arrays.asList(incident.getUserId().split(","));
        List<User> byIds = userMapper.findByIds(strings);

        if (byIds.size() > 0) {
            SendWeChatMessage weChat = new SendWeChatMessage();
            for (User byId : byIds) {
                String toUser = byId.getToUser();
                if ("".equals(toUser)) {
                    continue;
                }
                String content = "<div>" + TimesUntil.getDate("yyyy年MM月dd日 HH时mm分ss秒") + "</div> " +
                        "<div>" + incident.getText() + "</div>" +
                        "<div>" + foot + "</div>";
                weChat.sendWeChatMessage(
                        toUser, foot, content, "");
            }
        }
    }

    /**
     * 跟新数据
     */
    public void update(IncidentDto incidentDto) {
//        User me = UserContext.getUser();
//        System.out.println(incidentMapper.findByIdName(me.getTenantId(), incidentDto.getId(), incidentDto.getName()));
//        if (incidentMapper.findByName(me.getTenantId(), incidentDto.getName()) != null && incidentMapper.findByIdName(me.getTenantId(), incidentDto.getId(), incidentDto.getName()) == null) {
//            throw new BusinessException("名称已存在");
//        }
//
//        if (incidentMapper.findByIp(me.getTenantId(), incidentDto.getIp()) != null && incidentMapper.findByIdIp(me.getTenantId(), incidentDto.getId(), incidentDto.getIp()) == null) {
//            throw new BusinessException("ip已存在");
//        }
//        Incident gateway = new Incident();
//        gateway.setTenantId(me.getTenantId());
//        BeanUtils.copyProperties(incidentDto, gateway);
//        if (incidentMapper.update(gateway) != 1) {
//            throw new BusinessException("操作失败");
//        }
        if (incidentMapper.update(incidentDto) == 0) {
            throw new BusinessException("操作失败");
        }
    }

    /**
     * 创建事件记录
     */
//    public void notice(Incident incident1) throws Exception {
    @Transactional
    public void notice(String str, User user, Long levelId) throws Exception {
        MessageLogging messageLogging = new MessageLogging();
        messageLogging.setContent("请注意, " + str);
        messageLogging.setUserId(user.getId());
        messageLogging.setTenantId(user.getTenantId());
        messageLogging.setState("未处理");
        messageLoggingService.createMessageLogging(messageLogging);
        contextLoads(messageLogging.getId(), user.getTenantId()); //微信推送
        int times = 3;
        Level level = levelService.levelById(levelId);
        if (level != null && level.getTimes() > 0) {
            times = level.getTimes();
        }
        for (int i = 0; i < times; i++) {
            Thread thread1 = new Thread(() -> {
                String broadcast = "请注意, " + str;
                System.out.println("");
                webSocketServer.sendToken(user.getApiToken(), broadcast);
            });
            thread1.start();
        }
    }

    /**
     * 删除
     */
    public void deleteById(long id) {

        if (incidentMapper.deleteById(id, UserContext.getUser().getTenantId()) != 1) {
            throw new BusinessException("操作失败");
        }
    }

    /**
     * 推送微信消息
     */
    public void contextLoads(Long messageLoggingId, Long tenantId) {
        MessageLogging messageLogging = messageLoggingService.findById(tenantId, messageLoggingId);
        SendWeChatMessage weChat = new SendWeChatMessage();
        User user = userService.findUserById(messageLogging.getUserId());
        Date date = messageLogging.getCreatedAt();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
        String content = "<div>" + formatter.format(date) + "</div> " +
                "<div>" + messageLogging.getContent() + "</div>" +
                "<div>" + messageLogging.getState() + "</div>";

        if (user.getToUser() == null || "".equals(user.getToUser())) {
            return;
        }

        weChat.sendWeChatMessage(
                user.getToUser(), "异常呼叫", content, "");
    }

    /**
     * 推送消息
     */
    public void pushMessage() {
        List<Incident> list = incidentMapper.findCreatedAt();
        for (Incident incident : list) {
            Long time = new Date().getTime();
            Level level = levelService.levelById(incident.getLevelId());
            if (time >= incident.getCreatedAt().getTime() + level.getDuration() * 1000 * 60) {
                Level pid = levelService.levelByPid(level.getId());
                if (level.getHandle() == Level.HANDLE_CRAFT) {
//                    for (BoxEventUserDto boxEventUserDto : boxService.boxEventUserList(incident.getBoxId())) {
//                        if (incident.getEventId() == boxEventUserDto.getEventId()) {
//                            for (Long userId : boxEventUserDto.getUser().keySet()) {
//                                User user = userService.findById(userId);
//                                System.out.println("工艺负责人------------------------------------------------" + user.getName());
//                            }
//                        }
//                    }
                } else if (level.getHandle() == Level.HANDLE_LINE) {
                    Line line = lineService.findById(incident.getLineId());
                    User user = userService.findById(line.getUserId());
                    System.out.println("产线负责人------------------------------------------------" + user.getName());
                } else if (level.getHandle() == Level.HANDLE_WORKSHOP) {
                    Workshop workshop = workshopService.findById(incident.getWorkshopId());
                    User user = userService.findById(workshop.getUserId());
                    System.out.println("车间负责人------------------------------------------------" + user.getName());
                }
//                if (pid != null) {
//                    incidentMapper.updateLevelId(incident.getId(), pid.getId());
//                } else {
//                    System.out.println("最上级没有回应-----------------------");
//                }
            }
        }
    }

}
